LWG2442: call_once() shouldn't DECAY_COPY(). Patch from K-Ballo. This patch fixes LWG issue 2422 by removing the DECAY_COPY from call once. The review can be found here: http://reviews.llvm.org/D10191 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@239654 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/mutex b/include/mutex index e2a0daa..0adf1e6 100644 --- a/include/mutex +++ b/include/mutex 
@@ -442,7 +442,11 @@    template<class _Callable>  _LIBCPP_INLINE_VISIBILITY -void call_once(once_flag&, _Callable); +void call_once(once_flag&, _Callable&); + +template<class _Callable> +_LIBCPP_INLINE_VISIBILITY +void call_once(once_flag&, const _Callable&);    #endif // _LIBCPP_HAS_NO_VARIADICS   @@ -465,7 +469,11 @@  #else // _LIBCPP_HAS_NO_VARIADICS  template<class _Callable>  friend - void call_once(once_flag&, _Callable); + void call_once(once_flag&, _Callable&); + + template<class _Callable> + friend + void call_once(once_flag&, const _Callable&);  #endif // _LIBCPP_HAS_NO_VARIADICS  };   @@ -474,15 +482,10 @@  template <class _Fp>  class __call_once_param  { - _Fp __f_; + _Fp& __f_;  public: -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES  _LIBCPP_INLINE_VISIBILITY - explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit __call_once_param(const _Fp& __f) : __f_(__f) {} -#endif + explicit __call_once_param(_Fp& __f) : __f_(__f) {}    _LIBCPP_INLINE_VISIBILITY  void operator()() @@ -496,7 +499,7 @@  _LIBCPP_INLINE_VISIBILITY  void __execute(__tuple_indices<_Indices...>)  { - __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); + __invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...);  }  };   @@ -505,15 +508,10 @@  template <class _Fp>  class __call_once_param  { - _Fp __f_; + _Fp& __f_;  public: -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES  _LIBCPP_INLINE_VISIBILITY - explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {} -#else - _LIBCPP_INLINE_VISIBILITY - explicit __call_once_param(const _Fp& __f) : __f_(__f) {} -#endif + explicit __call_once_param(_Fp& __f) : __f_(__f) {}    _LIBCPP_INLINE_VISIBILITY  void operator()() @@ -543,9 +541,9 @@  {  if (__flag.__state_ != ~0ul)  { - typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp; - __call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)), - __decay_copy(_VSTD::forward<_Args>(__args))...)); + typedef tuple<_Callable&&, _Args&&...> _Gp; + _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); + __call_once_param<_Gp> __p(__f);  __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);  }  } @@ -555,7 +553,7 @@  template<class _Callable>  inline _LIBCPP_INLINE_VISIBILITY  void -call_once(once_flag& __flag, _Callable __func) +call_once(once_flag& __flag, _Callable& __func)  {  if (__flag.__state_ != ~0ul)  { @@ -564,6 +562,18 @@  }  }   +template<class _Callable> +inline _LIBCPP_INLINE_VISIBILITY +void +call_once(once_flag& __flag, const _Callable& __func) +{ + if (__flag.__state_ != ~0ul) + { + __call_once_param<const _Callable> __p(__func); + __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); + } +} +  #endif // _LIBCPP_HAS_NO_VARIADICS    _LIBCPP_END_NAMESPACE_STD